// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

void main(List<String> args) async {
  final testDataDirectory = Directory.fromUri(Platform.script.resolve('.'));
  updateManifest(testDataDirectory, false);
  final all = testDataDirectory.listSync(recursive: true);
  all.whereType<Directory>().forEach((e) => updateManifest(e, true));
}

const denyList = [
  '.dart_tool',
  'pubspec.lock',
  'manifest',
  'README.md',
  '.gitignore',
];

/// These just modify other test projects.
///
/// Don't add pubspecs to manifests, they contain a different name due to all
/// being part of a big workspace. They have a pubspec to enable analysis of
/// the Dart code in them.
const partialProjects = [
  'native_add_add_source',
  'native_add_add_symbol',
  'native_add_break_build',
  'native_add_fix_build',
  'simple_link_change_asset',
];

void updateManifest(Directory directory, bool allowPartialProjects) {
  final manifestFile = File.fromUri(directory.uri.resolve('manifest.yaml'));
  if (!manifestFile.existsSync()) {
    return;
  }
  final all = directory.listSync(recursive: true);
  final dirPath = directory.uri.toFilePath();
  final files =
      all
          .whereType<File>()
          .where((f) {
            for (final denyString in [
              ...denyList,
              if (!allowPartialProjects) ...partialProjects,
              for (final partialProject in partialProjects) ...[
                '$partialProject/pubspec.yaml',
              ],
            ]) {
              if (f.path.contains(denyString)) return false;
            }

            return true;
          })
          .map((e) => e.path.replaceFirst(dirPath, ''))
          .toList()
        ..sort();
  manifestFile.writeAsStringSync(header + files.map((e) => '- $e\n').join());
}

const header = '''
# The list of files to copy to a temporary folder to ensure running tests from
# a completely clean setup.
# Automatically generated by manifest_generator.dart.
''';
